{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from surprise import SVD\n",
    "from surprise import Dataset\n",
    "from surprise.model_selection import GridSearchCV"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Use movielens-100K\n",
    "data = Dataset.load_builtin('ml-100k')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "param_grid = {'n_epochs': [5, 10], 'lr_all': [0.002, 0.005],\n",
    "              'reg_all': [0.4, 0.6]}\n",
    "gs = GridSearchCV(SVD, param_grid, measures=['rmse', 'mae'], cv=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "gs.fit(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.964101450858\n"
     ]
    }
   ],
   "source": [
    "# best RMSE score\n",
    "print(gs.best_score['rmse'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'n_epochs': 10, 'lr_all': 0.005, 'reg_all': 0.4}\n"
     ]
    }
   ],
   "source": [
    "# combination of parameters that gave the best RMSE score\n",
    "print(gs.best_params['rmse'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<surprise.prediction_algorithms.matrix_factorization.SVD at 0x7fec751c6c18>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# We can now use the algorithm that yields the best rmse:\n",
    "algo = gs.best_estimator['rmse']\n",
    "algo.fit(data.build_full_trainset())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "results_df = pd.DataFrame.from_dict(gs.cv_results)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   mean_fit_time  mean_test_mae  mean_test_rmse  mean_test_time  param_lr_all  \\\n",
      "0       0.763213       0.806234        0.997454        0.218376         0.002   \n",
      "1       0.781401       0.814822        1.003486        0.233647         0.002   \n",
      "2       0.779605       0.782183        0.974052        0.214422         0.005   \n",
      "3       0.806645       0.793058        0.982727        0.234778         0.005   \n",
      "4       1.576031       0.786101        0.978228        0.215231         0.002   \n",
      "5       1.552500       0.796790        0.986485        0.210098         0.002   \n",
      "6       1.539839       0.772771        0.964101        0.209068         0.005   \n",
      "7       1.540987       0.784474        0.973873        0.209829         0.005   \n",
      "\n",
      "   param_n_epochs  param_reg_all  \\\n",
      "0               5            0.4   \n",
      "1               5            0.6   \n",
      "2               5            0.4   \n",
      "3               5            0.6   \n",
      "4              10            0.4   \n",
      "5              10            0.6   \n",
      "6              10            0.4   \n",
      "7              10            0.6   \n",
      "\n",
      "                                              params  rank_test_mae  \\\n",
      "0   {'n_epochs': 5, 'lr_all': 0.002, 'reg_all': 0.4}              7   \n",
      "1   {'n_epochs': 5, 'lr_all': 0.002, 'reg_all': 0.6}              8   \n",
      "2   {'n_epochs': 5, 'lr_all': 0.005, 'reg_all': 0.4}              2   \n",
      "3   {'n_epochs': 5, 'lr_all': 0.005, 'reg_all': 0.6}              5   \n",
      "4  {'n_epochs': 10, 'lr_all': 0.002, 'reg_all': 0.4}              4   \n",
      "5  {'n_epochs': 10, 'lr_all': 0.002, 'reg_all': 0.6}              6   \n",
      "6  {'n_epochs': 10, 'lr_all': 0.005, 'reg_all': 0.4}              1   \n",
      "7  {'n_epochs': 10, 'lr_all': 0.005, 'reg_all': 0.6}              3   \n",
      "\n",
      "   rank_test_rmse  split0_test_mae  split0_test_rmse  split1_test_mae  \\\n",
      "0               7         0.807229          0.999064         0.806149   \n",
      "1               8         0.815686          1.004874         0.814614   \n",
      "2               3         0.783984          0.976288         0.781981   \n",
      "3               5         0.794460          0.984654         0.792548   \n",
      "4               4         0.787780          0.980225         0.786185   \n",
      "5               6         0.798102          0.988382         0.796673   \n",
      "6               1         0.774781          0.966513         0.772832   \n",
      "7               2         0.786257          0.976102         0.784138   \n",
      "\n",
      "   split1_test_rmse  split2_test_mae  split2_test_rmse  std_fit_time  \\\n",
      "0          0.995416         0.805323          0.997883      0.004867   \n",
      "1          1.001413         0.814167          1.004171      0.001763   \n",
      "2          0.972207         0.780585          0.973662      0.003882   \n",
      "3          0.980589         0.792167          0.982938      0.019776   \n",
      "4          0.976590         0.784339          0.977868      0.016044   \n",
      "5          0.984622         0.795594          0.986450      0.013481   \n",
      "6          0.962463         0.770699          0.963329      0.002518   \n",
      "7          0.971910         0.783028          0.973607      0.002357   \n",
      "\n",
      "   std_test_mae  std_test_rmse  std_test_time  \n",
      "0      0.000781       0.001520       0.026922  \n",
      "1      0.000637       0.001494       0.006426  \n",
      "2      0.001395       0.001689       0.023883  \n",
      "3      0.001004       0.001666       0.034739  \n",
      "4      0.001406       0.001506       0.017609  \n",
      "5      0.001027       0.001535       0.024227  \n",
      "6      0.001667       0.001741       0.022471  \n",
      "7      0.001340       0.001721       0.024582  \n"
     ]
    }
   ],
   "source": [
    "print(results_df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
